package com.example.springboot.service;

import com.example.springboot.common.Constants;
import com.example.springboot.entity.*;
import com.example.springboot.entity.dto.UserDTO;
import com.example.springboot.exception.ServiceException;
import com.example.springboot.mapper.SysRoleMapper;
import com.example.springboot.mapper.SysRoleMenuMapper;
import com.example.springboot.mapper.SysUserMapper;
import com.example.springboot.utils.TokenUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: jyf2000jyf
 * @Date: 2022/4/27
 * @Time: 16:32
 * @Email: 904593011@qq.com
 * @Description:
 **/
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private SysRoleMapper roleMapper;

    @Autowired
    MenuService menuService;

    @Autowired
    private SysRoleMenuMapper roleMenuMapper;

    public Integer save(SysUser user) {
        if (user.getId() == null) {  // user没有id，则表示是新增
            return userMapper.insertSelective(user);
        } else { // 否则为更新
            return userMapper.updateByPrimaryKeySelective(user);
        }
    }

    @Override
    public List<SysUser> findAll() {
        return userMapper.selectByExample(null);
    }

    @Override
    public Integer delete(Integer id) {
        return userMapper.deleteByPrimaryKey(id);
    }

    @Override
    public List<SysUser> findAll(Integer pageNum, Integer pageSize, String username, String email, String contactPerson) {
        SysUserExample example = new SysUserExample();
        SysUserExample.Criteria criteria = example.createCriteria();
        example.setOrderByClause("create_time desc limit " + pageNum + "," + pageSize);
        if (username != null && !"".equals(username)) {
            criteria.andUsernameLike("%" + username + "%");
        }
        if (email != null && !"".equals(email)) {
            criteria.andEmailLike("%" + email + "%");
        }
        if (contactPerson != null && !"".equals(contactPerson)) {
            criteria.andContactPersonLike("%" + contactPerson + "%");
        }
        return userMapper.selectByExample(example);
    }

    @Override
    public Integer getAmount(String username, String email, String contactPerson) {
        SysUserExample example = new SysUserExample();
        SysUserExample.Criteria criteria = example.createCriteria();
        if (username != null && !"".equals(username)) {
            criteria.andUsernameLike("%" + username + "%");
        }
        if (email != null && !"".equals(email)) {
            criteria.andEmailLike("%" + email + "%");
        }
        if (contactPerson != null && !"".equals(contactPerson)) {
            criteria.andContactPersonLike("%" + contactPerson + "%");
        }
        return (Integer) (int) userMapper.countByExample(example);
    }

    @Override
    public void saveBatch(List<SysUser> users) {
        userMapper.deleteByExample(null);
        for (SysUser user : users) {
            userMapper.insertSelective(user);
        }
    }

    @Override
    public UserDTO login(UserDTO userDTO) {
        SysUserExample example = new SysUserExample();
        example.createCriteria().andUsernameEqualTo(userDTO.getUsername()).andPasswordEqualTo(userDTO.getPassword());
        List<SysUser> sysUsers = userMapper.selectByExample(example);
        if (sysUsers.size() == 1) {
            BeanUtils.copyProperties(sysUsers.get(0), userDTO);
            String token = TokenUtils.genToken(sysUsers.get(0).getId().toString(), sysUsers.get(0).getPassword());
            userDTO.setToken(token);

            String role = sysUsers.get(0).getRole();
            SysRoleExample sysRoleExample = new SysRoleExample();
            sysRoleExample.createCriteria().andFlagEqualTo(role);
            List<SysRole> sysRoles = roleMapper.selectByExample(sysRoleExample);
            if (sysRoles.size() != 1) {
                throw new ServiceException(Constants.CODE_500, "系统错误，请联系管理员");
            } else {
                List<SysMenu> roleMenus = getRoleMenus(sysRoles);
                userDTO.setMenus(roleMenus);
            }
            return userDTO;
        } else if (sysUsers.size() > 1) {
            throw new ServiceException(Constants.CODE_500, "系统错误，请联系管理员");
        } else {
            throw new ServiceException(Constants.CODE_600, "用户名或密码错误");
        }
    }

    @Override
    public UserDTO register(UserDTO userDTO) {
        SysUserExample example = new SysUserExample();
        example.createCriteria().andUsernameEqualTo(userDTO.getUsername());
        List<SysUser> sysUsers = userMapper.selectByExample(example);
        if (sysUsers.size() == 1) {
            throw new ServiceException(Constants.CODE_600, "用户已存在");
        } else if (sysUsers.size() > 1) {
            throw new ServiceException(Constants.CODE_500, "系统错误，请联系管理员");
        } else {
            SysUser sysUser = new SysUser();
            userDTO.setRole("ROLE_USER");
            BeanUtils.copyProperties(userDTO, sysUser);
            userMapper.insertSelective(sysUser);
            String token = TokenUtils.genToken(sysUser.getId().toString(), sysUser.getPassword());
            userDTO.setToken(token);
            return userDTO;
        }
    }

    @Override
    public SysUser getUserInfo(String username) {
        SysUserExample example = new SysUserExample();
        example.createCriteria().andUsernameEqualTo(username);
        List<SysUser> sysUsers = userMapper.selectByExample(example);
        if (sysUsers.size() != 1) {
            throw new ServiceException(Constants.CODE_500, "系统错误，请联系管理员");
        } else {
            return sysUsers.get(0);
        }
    }

    private List<SysMenu> getRoleMenus(List<SysRole> sysRoles) {
        SysRoleMenuExample roleMenuExample = new SysRoleMenuExample();
        roleMenuExample.createCriteria().andRoleIdEqualTo(sysRoles.get(0).getId());
        List<SysRoleMenuKey> roleMenuKeys = roleMenuMapper.selectByExample(roleMenuExample);
        List<Integer> menuIds = new ArrayList<>();
        for (SysRoleMenuKey roleMenuKey : roleMenuKeys) {
            menuIds.add(roleMenuKey.getMenuId());
        }

        List<SysMenu> menus = menuService.findAll();

        List<SysMenu> roleMenus = new ArrayList<>();

        for (SysMenu menu : menus) {
            if (menuIds.contains(menu.getId())) {
                roleMenus.add(menu);
            }
            List<SysMenu> children = menu.getChildren();
            children.removeIf(child -> !menuIds.contains(child.getId()));
        }
        return roleMenus;
    }

    @Override
    public Integer getUserIdByUsername(String username) {
        SysUserExample example = new SysUserExample();
        example.createCriteria().andUsernameEqualTo(username);
        List<SysUser> sysUsers = userMapper.selectByExample(example);
        if (sysUsers.size() == 1) {
            return sysUsers.get(0).getId();
        }
        return 0;
    }

    @Override
    public Integer getUserAmount() {
        SysUserExample example = new SysUserExample();
        example.createCriteria().andRoleEqualTo("ROLE_USER");
        return (Integer)(int)userMapper.countByExample(example);
    }

    @Override
    public Integer getNewUser() {
        return userMapper.countCurrentMonth();
    }
}
